﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using QUT.Bio.Map2D;
using QUT.Bio.Util;
using QUT.Bio.SilverMap.ObjectModel;

namespace QUT.Bio.SilverMap {
    /// <summary>
    /// Interaction logic for HorizontalLayout2.xaml
    /// </summary>
    public partial class HorizontalLayout2 : UserControl, IPageLayout {
        private bool initialised;
        private double alignmentHeaderWidth, summaryHeaderWidth;

        public HorizontalLayout2() {
            InitializeComponent();
            initialised = true;
        }

        public View View {
            get {
                return view;
            }
        }

        public HitStack Alignment {
            get {
                return alignment;
            }
        }

        public SequenceSummaryTable SequenceSummaryTable {
            get {
                return sequenceSummaryTable;
            }
        }

        public Grid GeneDetailsPanel {
            get {
                return geneDetailsPanel;
            }
        }

        public SequencePropertyPanel SequencePropertyPanel {
            get {
                return sequencePropertyPanel;
            }
        }

        /// <summary>
        /// Brings the specified user interface element into view.
        /// </summary>
        /// <param name="viewElement"></param>
        public void Show(FrameworkElement viewElement) {
            if (viewElement == geneDetailsPanel) {
                infoContainer.SelectedItem = geneDetailsContainer;
                geneDetailsContainer.Visibility = Visibility.Visible;
            } else if (viewElement == sequencePropertyPanel) {
                infoContainer.SelectedItem = sequencePropertyContainer;
            } else if (viewElement == sequenceSummaryTable) {
                infoContainer.SelectedItem = sequenceSummaryContainer;
            }

            // Everything else is already in view. Do nothing. 
        }

        /// <summary>
        /// Hides the specified user interface element into view.
        /// </summary>
        /// <param name="viewElement"></param>
        public void Hide(FrameworkElement viewElement) {
            if (viewElement == geneDetailsPanel) {
                if (infoContainer.SelectedItem == geneDetailsContainer) {
                    infoContainer.SelectedItem = sequencePropertyContainer;
                }

                geneDetailsContainer.Visibility = Visibility.Collapsed;
            }

            // Everything else is fixed. Do nothing.
        }

        /// <summary>
        /// Get a reference to the history control.
        /// </summary>
        public HistoryPanel HistoryPanel {
            get {
                return historyPanel;
            }
        }

        /// <summary>
        /// Gets a reference to the search control.
        /// </summary>
        public SearchControl SearchControl {
            get {
                return searchControl;
            }
        }

        private void infoContainer_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            if (!initialised) {
                return;
            }

            TextBlock[] tabLabels = {
				sequenceSummaryLiteral, sequencePropertyLiteral, geneDetailsLiteral
			};

            foreach (TextBlock tb in tabLabels) {
                tb.Visibility = Visibility.Collapsed;
            }

            if (infoContainer.SelectedItem == sequenceSummaryContainer) {
                sequenceSummaryLiteral.Visibility = Visibility.Visible;
            }

            if (infoContainer.SelectedItem == sequencePropertyContainer) {
                sequencePropertyLiteral.Visibility = Visibility.Visible;
            }

            if (infoContainer.SelectedItem == geneDetailsContainer) {
                geneDetailsLiteral.Visibility = Visibility.Visible;
            }
        }

        private void alignmentButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            Toggle((bool)alignmentToggle.IsChecked, alignmentExpander, alignmentHeaderWidth, alignmentColumn);
        }

        private void summaryButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            Toggle((bool)summaryToggle.IsChecked, summaryExpander, summaryHeaderWidth, summaryColumn);
        }

        private void SetExpanderColumnWidth(double newWidth, ColumnDefinition column) {
            column.Width = new GridLength(newWidth, GridUnitType.Pixel);
        }

        private void Toggle(
            bool isChecked,
            Expander expander,
            double collapsedWidth,
            ColumnDefinition column
        ) {
            expander.IsExpanded = isChecked;
            SetExpanderColumnWidth(
                isChecked ? expander.ActualWidth : collapsedWidth,
                column
            );
        }

        private void summaryExpander_Collapsed(object sender, System.Windows.RoutedEventArgs e) {
            summaryToggle.IsChecked = false;
            Toggle(false, summaryExpander, summaryHeaderWidth, summaryColumn);
        }

        private void alignmentExpander_Collapsed(object sender, System.Windows.RoutedEventArgs e) {
            alignmentToggle.IsChecked = false;
            Toggle(false, alignmentExpander, alignmentHeaderWidth, alignmentColumn);
        }

        private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) {
            UpdateExpander(
                alignmentExpander,
                alignmentPanel,
                (bool)alignmentToggle.IsChecked,
                alignmentColumn,
                e.HorizontalChange
            );
        }

        private void summaryThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) {
            UpdateExpander(
                summaryExpander,
                summaryPanel,
                (bool)summaryToggle.IsChecked,
                summaryColumn,
                -e.HorizontalChange
            );
        }

        private void UpdateExpander(
            Expander expander,
            Grid content,
            bool isPinned,
            ColumnDefinition column,
            double horizontalChange
        ) {
            const double HORIZONTAL_SCALE = 10;

            double marginWidth = expander.ActualWidth - content.ActualWidth;

            double newContentWidth = Math.Max(content.MinWidth, content.ActualWidth + (horizontalChange / HORIZONTAL_SCALE));

            content.Width = newContentWidth;

            if (isPinned) {
                column.Width = new GridLength(expander.ActualWidth, GridUnitType.Pixel);
            }
        }

        private void OnResize(object sender, SizeChangedEventArgs e) {
            // Prevent this from being called in future.
            SizeChanged -= OnResize;

            alignmentHeaderWidth = alignmentExpander.ActualWidth;
            summaryHeaderWidth = summaryExpander.ActualWidth;
            SetExpanderColumnWidth(alignmentHeaderWidth, alignmentColumn);
            SetExpanderColumnWidth(summaryHeaderWidth, summaryColumn);
        }

        private void alignmentExpander_MouseLeave(object sender, MouseEventArgs e) {
            if (alignmentToggle.IsChecked == false) {
                Toggle(false, alignmentExpander, alignmentHeaderWidth, alignmentColumn);
            }
        }

        private void summaryExpander_MouseLeave(object sender, MouseEventArgs e) {
            if (summaryToggle.IsChecked == false) {
                Toggle(false, summaryExpander, summaryHeaderWidth, summaryColumn);
            }
        }

        private void alignmentExpander_MouseEnter(object sender, MouseEventArgs e) {
            if (alignmentToggle.IsChecked == false) {
                Toggle(true, alignmentExpander, alignmentHeaderWidth, alignmentColumn);
            }
        }

        private void summaryExpander_MouseEnter(object sender, MouseEventArgs e) {
            if (summaryToggle.IsChecked == false) {
                Toggle(true, summaryExpander, summaryHeaderWidth, summaryColumn);
            }
        }
    }
}
